package com.hmj.excel.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hmj.excel.util.ArithHelper;
import com.hmj.excel.util.Calculator;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class FinanceService {

    public static void expressAndTax(String expression,List<JSONObject> dataList,Map title){
        //去掉所有空格
        expression = expression.replaceAll(" ","");
        Set<String> paramSet = parseExpression(expression);
        calcExpressAndTax(expression,paramSet,dataList,title);
    }

    /**
     * 解析表达式参数
     * @param expression
     * @return
     */
    private static Set<String> parseExpression(String expression){
        String spiltRules = "\\+|-|\\*|/|=|\\(|\\)";
        String[] arr = expression.split(spiltRules);
        Set<String> params = new HashSet<String>();
        for (String s : arr){
            if(StringUtils.isEmpty(s)){
                continue;
            }
            if (ArithHelper.isDouble(s) || ArithHelper.isInteger(s)){
                continue;
            }
            params.add(s);
        }
        return params;
    }

    /**
     * 计算个人所得
     * @param expression
     * @param params
     * @param dataList
     */
    private static void calcExpressAndTax(final String expression,final Set<String> params, List<JSONObject> dataList,Map title){
        int size = title.size();
        title.put(size,"total");
        title.put(size+1,"tax");

        for (JSONObject jsonObject : dataList){
            String tmoExpress = expression;
            Iterator<String> it = params.iterator();
            while (it.hasNext()){
                String value = it.next();
                String res = jsonObject.getString(value);
                if(StringUtils.isEmpty(res)){
                    res="0";
                }
                tmoExpress = tmoExpress.replaceAll(value,res);
            }
            double total = Calculator.conversion(tmoExpress);
            jsonObject.put("total",total);
            jsonObject.put("tax",getTax(total));
        }
    }

    /**
     * 计算个人所得税
     * @param total
     * @return
     */
    private static double getTax(double total){
        if(total<=0){
            return 0;
        }else if(total<=1500){
            return total*TaxEnum.Less1500.getTaxRate()/100-TaxEnum.Less1500.getQuickDeduction();
        }else if(total<=4500){
            return total*TaxEnum.Less4500.getTaxRate()/100-TaxEnum.Less4500.getQuickDeduction();
        }else if(total<=9000){
            return total*TaxEnum.Less9000.getTaxRate()/100-TaxEnum.Less9000.getQuickDeduction();
        }else if(total<=35000){
            return total*TaxEnum.Less35000.getTaxRate()/100-TaxEnum.Less35000.getQuickDeduction();
        }else if(total<=55000){
            return total*TaxEnum.Less55000.getTaxRate()/100-TaxEnum.Less55000.getQuickDeduction();
        }else if(total<=80000){
            return total*TaxEnum.Less80000.getTaxRate()/100-TaxEnum.Less80000.getQuickDeduction();
        }else if(total> 80000){
            return total*TaxEnum.LessMax.getTaxRate()/100-TaxEnum.LessMax.getQuickDeduction();
        }else {
            return 0;
        }
    }


    /**
     * 导出指定的列的不同数据
     * @param column
     * @param file1
     * @param file2
     * @param title
     * @return
     * @throws IOException
     */
    public static List<JSONObject> exportDiffExcel(String column, File file1, File file2,Map title) throws IOException {
        List<JSONObject> result = new ArrayList<JSONObject>();
        List<JSONObject> commonList1 = new ArrayList<JSONObject>();
        List<JSONObject> commonList2 = new ArrayList<JSONObject>();
        List<JSONObject> dataList1 = ExcelPrase.readExcelFile(file1, title);
        List<JSONObject> dataList2 = ExcelPrase.readExcelFile(file2,title);
        for (JSONObject jsonObject1 : dataList1){
            String value1 = jsonObject1.getString(column);
            jsonObject1.put("file",file1.getName());
            for (JSONObject jsonObject2 : dataList2){
                if(jsonObject1.getString(column)!=null && value1.equals(jsonObject2.getString(column))){
                    commonList1.add(jsonObject1);
                    commonList2.add(jsonObject2);
                    break;
                }
            }
        }

        dataList1.removeAll(commonList1);
        dataList2.removeAll(commonList2);

        for (JSONObject jsonObject2 : dataList2){
            jsonObject2.put("file",file2.getName());
        }
        title.put(title.size(),"file");
        result.addAll(dataList1);
        result.addAll(dataList2);
        return  result;
    }

    /**
     * 导出指定列的指定数据变化
     * @param column
     * @param changeColumn
     * @param file1
     * @param file2
     * @param title
     * @return
     * @throws IOException
     */
    public static List<JSONObject> exportChangeDataExcel(String column,String changeColumn, File file1, File file2,Map title) throws IOException {
        List<JSONObject> result = new ArrayList<JSONObject>();
        List<JSONObject> dataList1 = ExcelPrase.readExcelFile(file1, title);
        List<JSONObject> dataList2 = ExcelPrase.readExcelFile(file2,title);
        for (JSONObject jsonObject1 : dataList1){
            String value1 = jsonObject1.getString(column);
            for (JSONObject jsonObject2 : dataList2){
                if(value1!=null && value1.equals(jsonObject2.getString(column))){
                    String c1 = jsonObject1.getString(changeColumn);
                    String c2 = jsonObject2.getString(changeColumn);
                    if(c1==null && c2==null || c1!=null && c1.equals(c2) || c2!=null && c2.equals(c1)){
                        break;
                    }else{
                        jsonObject1.put("file",file1.getName());
                        jsonObject2.put("file",file2.getName());
                        result.add(jsonObject1);
                        result.add(jsonObject2);
                        break;
                    }

                }
            }
        }
        title.put(title.size(),"file");
        return  result;
    }
}
